/*
 * Copyright (C) 2013 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zhangyu.zxing;

import android.app.AlertDialog;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;


import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;

public final class PreferencesFragment extends PreferenceFragment implements
		SharedPreferences.OnSharedPreferenceChangeListener {

	private CheckBoxPreference[] checkBoxPrefs;

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		addPreferencesFromResource(R.xml.preferences);

		PreferenceScreen preferences = getPreferenceScreen();
		preferences.getSharedPreferences()
				.registerOnSharedPreferenceChangeListener(this);
		checkBoxPrefs = findDecodePrefs(preferences,
				PreferencesActivity.KEY_DECODE_1D_PRODUCT,
				PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL,
				PreferencesActivity.KEY_DECODE_QR,
				PreferencesActivity.KEY_DECODE_DATA_MATRIX,
				PreferencesActivity.KEY_DECODE_AZTEC,
				PreferencesActivity.KEY_DECODE_PDF417);
		disableLastCheckedPref();

		EditTextPreference customProductSearch = (EditTextPreference) preferences
				.findPreference(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH);
		customProductSearch
				.setOnPreferenceChangeListener(new CustomSearchURLValidator());
	}

	private static CheckBoxPreference[] findDecodePrefs(
			PreferenceScreen preferences, String... keys) {
		CheckBoxPreference[] prefs = new CheckBoxPreference[keys.length];
		for (int i = 0; i < keys.length; i++) {
			prefs[i] = (CheckBoxPreference) preferences.findPreference(keys[i]);
		}
		return prefs;
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		disableLastCheckedPref();
	}

	private void disableLastCheckedPref() {
		Collection<CheckBoxPreference> checked = new ArrayList<CheckBoxPreference>(
				checkBoxPrefs.length);
		for (CheckBoxPreference pref : checkBoxPrefs) {
			if (pref.isChecked()) {
				checked.add(pref);
			}
		}
		boolean disable = checked.size() <= 1;
		for (CheckBoxPreference pref : checkBoxPrefs) {
			pref.setEnabled(!(disable && checked.contains(pref)));
		}
	}

	private class CustomSearchURLValidator implements
			Preference.OnPreferenceChangeListener {
		@Override
		public boolean onPreferenceChange(Preference preference, Object newValue) {
			if (!isValid(newValue)) {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						PreferencesFragment.this.getActivity());
				builder.setTitle(R.string.msg_error);
				builder.setMessage(R.string.msg_invalid_value);
				builder.setCancelable(true);
				builder.show();
				return false;
			}
			return true;
		}

		private boolean isValid(Object newValue) {
			// Allow empty/null value
			if (newValue == null) {
				return true;
			}
			String valueString = newValue.toString();
			if (valueString.isEmpty()) {
				return true;
			}
			// Before validating, remove custom placeholders, which will not
			// be considered valid parts of the URL in some locations:
			// Blank %t and %s:
			valueString = valueString.replaceAll("%[st]", "");
			// Blank %f but not if followed by digit or a-f as it may be a hex
			// sequence
			valueString = valueString.replaceAll("%f(?![0-9a-f])", "");
			// Require a scheme otherwise:
			try {
				URI uri = new URI(valueString);
				return uri.getScheme() != null;
			} catch (URISyntaxException use) {
				return false;
			}
		}
	}

}
